import { HsAdminDelete, HsAdminPage, HsAdminSpin, HsAdminTable } from '@hs-admin/base-components'
import { message, usePage } from '@hs-admin/utils'
import { Button, Col, Divider, Dropdown, Flex, InputNumber, Modal, Row, Tag, Tooltip } from 'antd'
import type { MenuProps } from 'antd'
import { FC, Key, memo, useRef, useState } from 'react'
import './style.less'
import { QuestionCircleOutlined } from '@ant-design/icons'
import { reqDataItemColumns } from '@hs-admin/api'
import { ServerCoreField } from '@hs-server/components'
import { useImmer } from 'use-immer'
import { addDataItemSort, deleteDataItemSort, editDataItemSort, getDataItemPolymerizeOptions, getDataItemSortList } from '@/api/setting/item'
import { getKeyValueArr } from '@/utils/tools'
import List from 'rc-virtual-list'

interface Props {
  id: string
}
const Sort: FC<Props> = (props: Props) => {
  const { id } = props
  const [dataSortList, setdataSortList] = useState<any[]>([])
  const [modalTitle, setmodalTitle] = useState('')
  const [dropKey, setdropKey] = useState('')
  const [tableData, setTableData] = useImmer<any[]>([])
  const [isOpen, setIsOpen] = useState(false)
  const [polymerizationName, setpolymerizationName] = useState<{ field: string; comment: string }>({
    field: '',
    comment: ''
  })
  const [loading, setloading] = useState(true)
  const [fieldList, setfieldList] = useImmer<any[]>([])
  const [itemInfor, setitemInfor] = useState({})
  const [polymerizeOptions, setpolymerizeOptions] = useImmer<any[]>([])

  const dropSelect = (key: string, item: { value?: string; label?: string; tooltip?: string; disabled?: any }) => {
    if (item.disabled) {
      return
    }
    setdropKey(key)
    setIsOpen(true)
    setmodalTitle(dataItemSortType(key))
    switch (key) {
      case 'search_hits':
        reqDataItemColumns({ id }).then((res) => {
          setTableData(res.filter((item: { searchable: any }) => item.searchable).map((item: any) => ({ ...item, score: 0 })))
        })
        break
      default:
        break
    }
  }
  const callEdit = (item: any) => {
    const {
      config: { fields }
    } = item
    setdropKey(item.type)
    setIsOpen(true)
    setmodalTitle(dataItemSortType(item.type))
    setfieldList(fields)
    setitemInfor(item)
    switch (item.type) {
      case 'search_hits':
        reqDataItemColumns({ id }).then((res) => {
          setTableData(
            res
              .filter((item: { searchable: any }) => item.searchable)
              .map((item: { name: any }) => ({
                ...item,
                score: fields.find((ele: { field: any }) => ele.field === item.name)?.score
              }))
          )
        })
        break
      case 'polymerize':
        setpolymerizationName(fields[0])
        getDataItemPolymerizeOptions({ release_item_id: id, column_name: fields[0].field }).then((res) => {
          setpolymerizeOptions(
            res.map((ele: string, index: number) => {
              const findScore = fields[0].options.find((element: { option: string }) => element.option === ele)
              if (findScore) {
                return {
                  option: ele,
                  score: findScore.score,
                  key: `${ele}${index}`
                }
              } else {
                return {
                  option: ele,
                  score: 0,
                  key: `${ele}${index}`
                }
              }
            })
          )
        })
        break
      default:
        break
    }
  }
  const dataItemSortType = (value?: string) => {
    const list = [
      {
        label: '搜索命中字段权重排序',
        value: 'search_hits',
        tooltip: '为每个”可搜索“字段设置权重，搜索的查询结果，将按照关键词命中字段的权重进行排列'
      },
      { label: '不为空字段排序', value: 'not_null', tooltip: '选择某个或多个字段进行不为空排序，查询结果中，被选择字段如果不为空将会排序靠前' },
      {
        label: '聚合结果权重排序',
        value: 'polymerize',
        tooltip: '为某一可聚合字段的各项聚合结果设置权重，查询结果会将高权重聚合项所对应的数据排序靠前'
      },
      { label: '时间排序', value: 'time', tooltip: '选择某一或多个时间字段，查询结果可以手动进行时间先后排序，如果内容不是时间格式，将无法正常排序' },
      {
        label: '数值排序',
        value: 'numeric',
        tooltip: '选择某一或多个数值字段，查询结果可以手动进行数值大小排序，如果内容不是数值格式，将无法正常排序'
      }
    ]
    return getKeyValueArr(value, list)
  }
  const [items, setItems] = useState<MenuProps['items']>([])
  const columns = [
    {
      title: '字段名',
      dataIndex: 'name'
    },
    {
      title: '中文名',
      dataIndex: 'comment',
      ellipsis: true
    },
    {
      title: '权重值(0-100)',
      dataIndex: 'score',
      render: (_: any, record: any, index: number) => (
        <InputNumber
          type="number"
          min={0}
          max={100}
          value={record.score}
          onChange={(value) =>
            setTableData((prev) => {
              prev[index].score = value
            })
          }
        />
      )
    }
  ]

  const callList = () => {
    setloading(true)
    return getDataItemSortList({ release_item_id: id, page: pagination.current, page_size: pagination.pageSize })
      .then((res) => {
        setdataSortList(
          res.items.map((item: any) => ({
            ...item,
            updateType: 'edit'
          }))
        )
        setItems((prev) => {
          prev = dataItemSortType().map((item: { value: string; label: string; tooltip: string }) => ({
            ...item,
            key: item.value,
            disabled: false
          }))
          prev?.forEach((item: any) => {
            if (item.key !== 'polymerize') {
              const hasFlag = res.items.find((ele: { type: Key | undefined }) => ele.type === item.key)
              if (hasFlag) {
                item.disabled = true
              }
            }
            item.label = (
              <Flex gap={'small'} onClick={() => dropSelect(item.value, item)}>
                <a>{item.label}</a>
                <Tooltip title={item.tooltip}>
                  <QuestionCircleOutlined />
                </Tooltip>
              </Flex>
            )
          })
          return prev
        })

        return res
      })
      .finally(() => {
        setloading(false)
      })
  }
  const { pagination }: { pagination: UsePageProps } = usePage(callList)
  const handleOk = async () => {
    const params: any = { release_item_id: id, type: dropKey, ...itemInfor }
    switch (dropKey) {
      case 'search_hits':
        params.config = {
          fields: tableData.map((item) => ({
            field: item.name,
            comment: item.comment,
            score: +item.score
          }))
        }
        break
      case 'polymerize':
        if (!polymerizationName.field) {
          message.warning('字段不能为空')
          return
        }
        params.config = {
          fields: [
            {
              field: polymerizationName.field,
              comment: polymerizationName.comment,
              options: polymerizeOptions
                .filter((item) => item.score)
                .map((item) => ({
                  option: item.option,
                  score: item.score
                }))
            }
          ]
        }
        break
      case 'not_null':
      case 'time':
      case 'numeric':
        if (!fieldList.length) {
          message.warning('请添加字段')
          return
        }
        for (const item of fieldList) {
          if (!item.field) {
            message.warning('字段不能为空')
            return
          }
        }
        params.config = {
          fields: fieldList
        }
        break
      default:
        break
    }
    if (params.id) {
      editDataItemSort(params).then(() => {
        callList()
        handleCancel()
      })
    } else {
      addDataItemSort(params).then(() => {
        callList()
        handleCancel()
      })
    }
  }
  const handleCancel = () => {
    setIsOpen(false)
    setdropKey('')
    setTableData([])
    setpolymerizationName({
      field: '',
      comment: ''
    })
    setfieldList([])
    setitemInfor({})
    setpolymerizeOptions([])
  }

  return (
    <>
      {loading && <HsAdminSpin />}
      <Divider />
      <h2>排序规则配置：</h2>
      <Dropdown menu={{ items }}>
        <Button className="mt-7" size="large" type="primary">
          + 新增排序规则
        </Button>
      </Dropdown>
      <br />
      <br />
      <Row gutter={[16, 16]}>
        {dataSortList.map((item) => (
          <Col span={6} key={item.id}>
            <div className="data-list-item">
              <Flex align="center" justify="space-between">
                <h3>{dataItemSortType(item.type)}</h3>
                <Tag color={item.updateType === 'edit' ? 'green' : 'red'}>{item.updateType === 'edit' ? '已编辑' : '未编辑'}</Tag>
              </Flex>
              <br />
              <Flex align="center" justify="space-between">
                <div>{item.type !== 'time' && item.type !== 'numeric' && <p>权重：{item.score_range ?? 0}</p>}</div>
                <Button type="link" size="small" onClick={() => callEdit(item)}>
                  去编辑
                </Button>
              </Flex>
              <HsAdminDelete
                iconClassName="delete-icon"
                onConfirm={() => {
                  deleteDataItemSort({ release_item_id: id, id: item.id }).then(() => {
                    callList()
                  })
                }}
              />
            </div>
          </Col>
        ))}
      </Row>
      <br />
      <Flex justify="flex-end">
        <HsAdminPage {...pagination} />
      </Flex>
      <Modal title={modalTitle} open={isOpen} onOk={handleOk} onCancel={handleCancel} width={600}>
        {/* 搜索命中字段权重排序 */}
        {dropKey === 'search_hits' && (
          <HsAdminTable id="J-data-item-sort-rule" columns={columns} dataSource={tableData} rowKey="id" pagination={false} />
        )}
        {/* 不为空字段排序 */}
        {dropKey === 'not_null' && (
          <AddField
            id={id}
            title="不为空字段选择"
            dropKey={dropKey}
            fieldList={fieldList}
            disabledField={fieldList.map((item) => item.field)}
            updateFieldList={(list) => setfieldList(list)}
          />
        )}
        {/* 聚合结果权重排序 */}
        {dropKey === 'polymerize' && (
          <>
            <Flex className="mb-4">字段选择</Flex>
            <SelectField
              id={id}
              field={polymerizationName.field}
              updateField={(value, option: any) => {
                setpolymerizationName({
                  field: option.name,
                  comment: option.comment
                })
                getDataItemPolymerizeOptions({ release_item_id: id, column_name: value }).then((res) => {
                  setpolymerizeOptions(
                    res.map((ele: string, index: number) => ({
                      option: ele,
                      score: 0,
                      key: `${ele}${index}`
                    }))
                  )
                })
              }}
            />
            <Row className="mt-4">
              <Col span={12}>聚合项</Col>
              <Col span={12}>权重值(0-100)</Col>
            </Row>
            <List data={polymerizeOptions} height={500} itemHeight={30} itemKey="key">
              {(item, index) => (
                <Row className="pt-4" align="middle">
                  <Col span={12}>
                    <p className="flex-none">{item.option}</p>
                  </Col>
                  <Col span={12}>
                    <InputNumber
                      type="number"
                      min={0}
                      max={100}
                      value={item.score}
                      onChange={(value) =>
                        setpolymerizeOptions((prev) => {
                          prev[index].score = value
                        })
                      }
                    />
                  </Col>
                </Row>
              )}
            </List>
          </>
        )}
        {/* 时间排序 */}
        {dropKey === 'time' && (
          <AddField
            id={id}
            title="时间字段选择"
            dropKey={dropKey}
            fieldList={fieldList}
            disabledField={fieldList.map((item) => item.field)}
            updateFieldList={(list) => setfieldList(list)}
          />
        )}
        {/* 数值排序 */}
        {dropKey === 'numeric' && (
          <AddField
            id={id}
            title="数值字段选择"
            dropKey={dropKey}
            fieldList={fieldList}
            disabledField={fieldList.map((item) => item.field)}
            updateFieldList={(list) => setfieldList(list)}
          />
        )}
      </Modal>
    </>
  )
}

interface SelectFieldProps {
  id: string
  field: string
  disabledField?: string[]
  updateField: (field: string, option: { comment: string }) => void
}
const SelectField: FC<SelectFieldProps> = (props: SelectFieldProps) => {
  const { id, field, disabledField, updateField } = props
  const coreFieldRef = useRef<any>({})

  return (
    <>
      <Button
        onClick={() => {
          coreFieldRef.current.showModal(id, field)
        }}
        style={{
          color: field ? 'rgba(0, 0, 0, 0.88)' : 'rgba(0, 0, 0, 0.25)'
        }}>
        {field || '请选择字段'}
      </Button>
      <ServerCoreField
        ref={coreFieldRef}
        disabledField={disabledField}
        onSelectChange={(value: string, option: { comment: string }) => {
          updateField(value, option)
          return Promise.resolve()
        }}
      />
    </>
  )
}

interface AddFieldProps {
  id: string
  title: string
  dropKey: string
  fieldList: any[]
  disabledField?: string[]
  updateFieldList: (list: any[]) => void
}
const AddField: FC<AddFieldProps> = (props: AddFieldProps) => {
  const { id, title, dropKey, fieldList, disabledField, updateFieldList } = props
  const localFieldList = [...fieldList]

  return (
    <>
      <Row>
        <Col span={12}>{title}</Col>
        {dropKey === 'not_null' && <Col span={12}>权重值(0-100)</Col>}
      </Row>
      {fieldList.map((item, index) => (
        <Row key={index} className="mt-4">
          <Col span={12}>
            <HsAdminDelete
              onConfirm={() => {
                localFieldList.splice(index, 1)
                updateFieldList(localFieldList)
              }}
              className="mr-2"
            />
            <SelectField
              id={id}
              field={item.field}
              disabledField={disabledField}
              updateField={(value: string, option: { comment: string }) => {
                localFieldList[index].field = value
                localFieldList[index].comment = option.comment
                updateFieldList(localFieldList)
              }}
            />
          </Col>
          {dropKey === 'not_null' && (
            <Col span={12}>
              <InputNumber
                type="number"
                min={0}
                max={100}
                value={item.score}
                onChange={(value) => {
                  localFieldList[index].score = +value
                  updateFieldList(localFieldList)
                }}
              />
            </Col>
          )}
        </Row>
      ))}
      <br />
      <Row>
        <Col span={12}>
          <Button
            type="primary"
            onClick={() => {
              if (dropKey === 'not_null') {
                localFieldList.push({ field: '', comment: '', score: 0 })
              } else {
                localFieldList.push({ field: '', comment: '' })
              }
              updateFieldList(localFieldList)
            }}>
            +添加字段
          </Button>
        </Col>
      </Row>
    </>
  )
}

export default memo(Sort)
